<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
</body>
<!-- Line -->
<script id="LineVertexShader" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    uniform float u_PointSize;
    uniform mat4 u_ModelM4;
    void main(){
        gl_Position = u_ModelM4 * a_Position;
        gl_PointSize = u_PointSize;
    }
</script>
<script id="LineFragmentShader" type="x-shader/x-fragment">
    precision mediump float;
    void main(){
        gl_FragColor = vec4(1,1,1,1);
    }
</script>
<!-- Face -->
<script id="FaceVertexShader" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    uniform mat4 u_ModelM4;
    void main(){
        gl_Position = u_ModelM4 * a_Position;
    }
</script>
<script id="FaceFragmentShader" type="x-shader/x-fragment">
    precision mediump float;
    uniform float u_Time;
    void main(){
        gl_FragColor = vec4((sin(u_Time / 200.0) + 1.0) / 2.0, 1, 1, 1);
    }
</script>
<script type="module">
    import { Matrix4, Vector3, Color, PerspectiveCamera, Spherical } from '../js/three.module.js';
    import Poly from '../js/Poly4.js';
    import { initShaders, CreateProgram } from '../js/Utils.js';
    import lib from '../js/ThreeLib.js';
    import CameraController from '../js/CameraController.js'


    //#region gl
    const canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight - 4;

    const gl = canvas.getContext("webgl");
    //开始背景遮挡
    gl.enable(gl.DEPTH_TEST);
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    //#endregion

    let lineProgram, lineBuffer, lineElementBuffer;
    let faceProgram, faceBuffer, faceElementBuffer;
    let u_Time;

    const lineNodes = [
        -0.2, 0.2,
        -0.2, -0.2,
        0.2, -0.2,
        0.2, 0.2,
    ];
    const lineElement = [
        0, 1,
        1, 2,
        2, 3,
        3, 0
    ];
    const faceElement = [
        0, 1, 2,
        0, 2, 3
    ];






    function InitLineShader() {
        //创建程序对象
        lineProgram = CreateProgram(gl,
            document.querySelector('#LineVertexShader').innerText,
            document.querySelector('#LineFragmentShader').innerText);
        //启动程序对象
        gl.useProgram(lineProgram);

        //创建缓冲区对象
        lineBuffer = gl.createBuffer();
        //绑定缓冲区对象
        gl.bindBuffer(gl.ARRAY_BUFFER, lineBuffer);
        //写入顶点数据
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(lineNodes), gl.STATIC_DRAW);

        //写入变量数据
        let a_Position = gl.getAttribLocation(lineProgram, 'a_Position');
        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 2 * 4, 0 * 4);
        gl.enableVertexAttribArray(a_Position);//激活索引位置

        let u_PointSize = gl.getUniformLocation(lineProgram, 'u_PointSize');
        gl.uniform1f(u_PointSize, 20);

        let u_ModelM4 = gl.getUniformLocation(lineProgram, 'u_ModelM4');
        gl.uniformMatrix4fv(u_ModelM4, false, new Matrix4().setPosition(-0.3, 0, 0).elements);

        lineElementBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, lineElementBuffer);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array(lineElement), gl.STATIC_DRAW);

    }

    function InitFaceShader() {
        faceProgram = CreateProgram(gl,
            document.querySelector('#FaceVertexShader').innerText,
            document.querySelector('#FaceFragmentShader').innerText);
        gl.useProgram(faceProgram);

        faceBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, faceBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(lineNodes), gl.STATIC_DRAW);

        let a_Position = gl.getAttribLocation(faceProgram, 'a_Position');
        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 2 * 4, 0 * 4);
        gl.enableVertexAttribArray(a_Position);

        let u_ModelM4 = gl.getUniformLocation(faceProgram, 'u_ModelM4');
        gl.uniformMatrix4fv(u_ModelM4, false, new Matrix4().setPosition(0.3, 0, 0).elements);

        u_Time = gl.getUniformLocation(faceProgram, 'u_Time');

        faceElementBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, faceElementBuffer);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array(faceElement), gl.STATIC_DRAW);

    }


    lib.clearCanvas(gl, new Color("rgba(0,0,0,255)"), 1);
    InitLineShader();
    InitFaceShader();

    Rend();


    (function ani(time = 0) {
        lib.clearCanvas(gl, new Color("rgba(0,0,0,255)"), 1);

        Rend(time);

        requestAnimationFrame(ani);
    })();

    function Rend(time = 0) {
        //优先进行启动程度对象
        gl.useProgram(lineProgram);
        //在绑定程序对象
        gl.bindBuffer(gl.ARRAY_BUFFER, lineBuffer);
        //每次绑定缓冲区对象
        //是为了修改缓冲区的值
        //与进行渲染对象
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(lineNodes), gl.STATIC_DRAW);
        //目前不知道为什么需要从新写入顶点数据, 大概是如果更新了新的顶点着需要,目前无作用
        gl.drawArrays(gl.POINTS, 0, lineNodes.length / 2);

        //如果使用了ELEMENT渲染,着必须进行一次绑定后才能渲染,贴图同理
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, lineElementBuffer);
        gl.drawElements(gl.LINES, lineElement.length, gl.UNSIGNED_BYTE, 0);


        gl.useProgram(faceProgram);
        gl.bindBuffer(gl.ARRAY_BUFFER, faceBuffer);
        gl.uniform1f(u_Time, time);
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, faceElementBuffer)
        gl.drawElements(gl.TRIANGLES, faceElement.length, gl.UNSIGNED_BYTE, 0);


    }
</script>

</html>